package org.jeecg.modules.scm.controller;

import cfca.trustsign.common.vo.cs.ContractVO;
import cfca.trustsign.common.vo.cs.UploadContractVO;
import cfca.trustsign.demo.op.CfcaOp;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.vo.ScmResInfoVo;
import org.jeecg.modules.flow.api.FlowBaseCloudApi;
import org.jeecg.modules.flow.vo.HistoryActivityInstanceVo;
import org.jeecg.modules.scm.common.util.HttpRequest;
import org.jeecg.modules.scm.dto.BankDataDto;
import org.jeecg.modules.scm.dto.BankLendingDto;
import org.jeecg.modules.scm.dto.BankReviewDto;
import org.jeecg.modules.scm.entity.ScmFinaApply;
import org.jeecg.modules.scm.service.IScmFinaApplyService;
import org.jeecg.modules.scm.vo.FinaApplyTaskVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.support.PagedListHolder;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
 /**
 * @Description: scm_fina_apply
 * @Author: jeecg-boot
 * @Date:   2021-11-10
 * @Version: V1.0
 */
@Api(tags="融资申请")
@RestController
@RequestMapping("/fina_apply/scmFinaApply")
@Slf4j
@MultipartConfig
public class ScmFinaApplyController extends JeecgController<ScmFinaApply, IScmFinaApplyService> {
	@Autowired
	private IScmFinaApplyService scmFinaApplyService;
	 /**
	  * 流程调用api
	  * */
	@Autowired
	private FlowBaseCloudApi flowBaseCloudApi;

	 @Autowired
	 @Lazy
	 private RedisUtil redisUtil;

	 /**
	 * 分页列表查询，查看当前用户的所有申请状态
	 *
	 * @param scmFinaApply
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	@AutoLog(value = "分页列表查询,查看当前用户的所有申请状态")
	@ApiOperation(value="分页列表查询", notes="分页列表查询,查看当前用户的所有申请状态")
	@GetMapping(value = "/list")
	public Result<?> queryPageList(ScmFinaApply scmFinaApply,
								   @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
								   @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
								   HttpServletRequest req) {
		LoginUser sysUser = SecurityUtils.getSubject().getPrincipal() != null ?
				(LoginUser) SecurityUtils.getSubject().getPrincipal() : null;
		if(sysUser==null){
			throw new JeecgBootException("用户不存在");
		}
		scmFinaApply.setCreateBy(sysUser.getUsername());
		QueryWrapper<ScmFinaApply> queryWrapper = QueryGenerator.initQueryWrapper(scmFinaApply, req.getParameterMap());
		Page<ScmFinaApply> page = new Page<ScmFinaApply>(pageNo, pageSize);
		IPage<ScmFinaApply> pageList = scmFinaApplyService.page(page, queryWrapper);
		return Result.OK(pageList);
	}
	/**
	 * 进度查询
	 *
	 * */
	@AutoLog(value = "进度查询")
	@Transactional(rollbackFor = Exception.class)
	@ApiOperation(value="进度查询", notes="进度查询")
	@GetMapping(value = "/processQuery")
	public Result<?> processQuery(
			@RequestParam(name="applyNo") Integer applyNo,
			@RequestParam(name="pageNo",defaultValue = "0") Integer pageNo,
			@RequestParam(name="pageSize",defaultValue = "10") Integer pageSize ) throws IllegalAccessException {

		List<Map> maps = scmFinaApplyService.processQuery(applyNo, pageNo, pageSize);
		//		List<SupplyChainVo> supplyChainVos = scmSupplyChainService.pageSearch(pageSearchOfChainDto);
		PagedListHolder<Map> pagedListHolder = new PagedListHolder<>(maps);
		pagedListHolder.setPageSize(pageSize);
		pagedListHolder.setPage(pageNo);
		return Result.OK(pagedListHolder);

	}

	/**
	 *   添加，注入当前用户以及日期
	 *
	 * @param scmFinaApply
	 * @return
	 */
	@AutoLog(value = "scm_fina_apply-添加")
	@ApiOperation(value="scm_fina_apply-添加", notes="scm_fina_apply-添加")
	@PostMapping(value = "/add")
	public Result<?> add(@RequestBody ScmFinaApply scmFinaApply) {
//		自动拦截注入
//		LoginUser sysUser = SecurityUtils.getSubject().getPrincipal() != null ?
//				(LoginUser) SecurityUtils.getSubject().getPrincipal() : null;
//		if(sysUser==null){
//			throw new JeecgBootException("用户不存在");
//		}
//		Date cur = new Date();
//		scmFinaApply.setCreationUser(sysUser.getUsername());
//		scmFinaApply.setLastModifyUser(sysUser.getUsername());
//		scmFinaApply.setCreationDate(cur);
//		scmFinaApply.setLastModifyDate(cur);
		scmFinaApply.setApplyState(1);
		//TODO 检查到期日，需再额外拿到数字债权凭证日期
		scmFinaApplyService.check(scmFinaApply);
		scmFinaApplyService.save(scmFinaApply);
		return Result.OK(scmFinaApply.getApplyNo());
	}

	/**
	 *  编辑
	 *
	 * @param scmFinaApply
	 * @return
	 */
	@AutoLog(value = "scm_fina_apply-编辑")
	@ApiOperation(value="scm_fina_apply-编辑", notes="scm_fina_apply-编辑")
	@PutMapping(value = "/edit")
	public Result<?> edit(@RequestBody ScmFinaApply scmFinaApply) {
		ScmFinaApply checkApply = scmFinaApplyService.getById(scmFinaApply.getApplyNo());
		if(checkApply.getApplyState()!=1){
			throw new JeecgBootException("当前状态不可编辑");
		}
		scmFinaApplyService.updateById(scmFinaApply);

		return Result.OK("编辑成功!");
	}

	/**
	 *   通过id删除
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "scm_fina_apply-通过id删除")
	@ApiOperation(value="scm_fina_apply-通过id删除", notes="scm_fina_apply-通过id删除")
	@DeleteMapping(value = "/delete")
	public Result<?> delete(@RequestParam(name="id",required=true) String id) {
		scmFinaApplyService.removeById(id);
		return Result.OK("删除成功!");
	}

	/**
	 *  批量删除
	 *
	 * @param ids
	 * @return
	 */
	@AutoLog(value = "scm_fina_apply-批量删除")
	@ApiOperation(value="scm_fina_apply-批量删除", notes="scm_fina_apply-批量删除")
	@DeleteMapping(value = "/deleteBatch")
	public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		this.scmFinaApplyService.removeByIds(Arrays.asList(ids.split(",")));
		return Result.OK("批量删除成功!");
	}

	/**
	 * 通过id查询
	 *
	 * @param id
	 * @return
	 */
	@AutoLog(value = "scm_fina_apply-通过id查询")
	@ApiOperation(value="scm_fina_apply-通过id查询", notes="scm_fina_apply-通过id查询")
	@GetMapping(value = "/queryById")
	public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
		ScmFinaApply scmFinaApply = scmFinaApplyService.getById(id);
		if(scmFinaApply==null) {
			return Result.error("未找到对应数据");
		}
		return Result.OK(scmFinaApply);
	}

	/**
	 * 启动融资申请实例
	 * */
	@AutoLog(value = "scm_fina_apply-启动融资申请实例")
	@Transactional(rollbackFor = Exception.class)
 	@ApiOperation(value="scm_fina_apply-启动融资申请实例", notes="scm_fina_apply-启动融资申请实例")
 	@GetMapping("/startFinaApply")
 	Result<?> startInstanceByProKey(@RequestParam(name="applyNos",required=true) String applyNos)
 	{
 		String[] tmp = applyNos.split(",");
 		Integer[] Nos = new Integer[tmp.length];
 		for(int i=0;i<tmp.length;i++){
 			Nos[i] = Integer.parseInt(tmp[i]);
		}
		ScmResInfoVo scmResInfoVo = scmFinaApplyService.startInstance(Nos);
		return Result.OK(scmResInfoVo);
 	}



	 @ApiOperation(value = "上传附件", notes = "上传附件")
	 @PostMapping("/uploadFile")
	 public Result<?> uploadFile(@RequestBody MultipartFile[] files,@RequestParam(name = "applyNo") Integer applyNo) {
		 String res = scmFinaApplyService.uploadAccessory(files, applyNo);
		 return Result.OK(res);
	 }

//	 @AutoLog(value = "通过当前用户获取融资申请信息")
//	 @ApiOperation(value = "通过当前用户获取融资申请信息", notes = "通过当前用户获取融资申请信息")
//	 @PostMapping("/getApplyInfo")
//	 public Result<?> getApplyInfo() {
//		 List<ScmFinaApply> applyInfo = scmFinaApplyService.getApplyInfo();
//		 return Result.OK(applyInfo);
//	 }

	 @AutoLog(value = "获取当前用户待办任务")
	 @ApiOperation(value = "获取当前用户待办任务", notes = "获取当前用户待办任务")
	 @GetMapping("/getExecutableApplyInfo")
	 public Result<?> getExecutableApplyInfo(@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
											 @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
		 List<FinaApplyTaskVo> applyInfo = scmFinaApplyService.getExecutableApplyInfo();
		 PagedListHolder<FinaApplyTaskVo> pagedListHolder = new PagedListHolder<>(applyInfo);
		 pagedListHolder.setPageSize(pageSize);
		 pagedListHolder.setPage(pageNo);
		 return Result.OK(pagedListHolder);
	 }

	 @AutoLog(value = "完成指定任务业务")
	 @ApiOperation(value = "完成指定任务业务", notes = "完成指定任务业务")
	 @PostMapping("/completeTask")
	 public Result<?> completeTask(@RequestParam(name="applyNo",required = true) Integer applyNo,
								   @RequestParam(name="taskName",required = true) String taskName,
								   @RequestParam(name="result",required = true) boolean result
								   ) {
//		此处用于流程外的业务完成其业务
//		scmFinaApplyService.executeTask(taskName,applyNo,result);
		return Result.OK("完成"+taskName+"任务业务");
	 }

	 /*
	 * public void processComplete(Integer applyNo, String comment, Integer submitType)
	 *
	 * */
	 @AutoLog(value = "完成指定任务")
	 @Transactional(rollbackFor = Exception.class)
	 @ApiOperation(value = "完成指定任务", notes = "完成指定任务submitType：1同意、2撤回、3终结")
	 @GetMapping("/processComplete")
	 public Result<?> processComplete(@RequestParam(name="applyNo",required = true) Integer applyNo,
									  @RequestParam(name="comment",required = true) String comment,
									  @RequestParam(name="submitType",required = true) Integer submitType,
									  @RequestParam(name="backProcessType") Integer backProcessType

	 ) {
//		此处用于流程外的业务完成其业务

		 return scmFinaApplyService.processComplete(applyNo,comment, submitType,backProcessType);
	 }


	 /**
	  * 以下仅作测试，需要nacos 过滤token
	  * submitType为1和4时不执行flow
	  * **/
	 @Transactional(rollbackFor = Exception.class)
	 @ApiOperation(value = "银行接收审批接口", notes = "银行接收接口")
	 @PostMapping(value = "/bank/bankCheckReceive",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
	 public Result<?> bankReceive(@RequestParam(value = "bankDataDto") String bankDataDtos, @RequestPart(required = false) MultipartFile templateContract){

		 BankDataDto bankDataDto = JSONObject.toJavaObject(JSONObject.parseObject(bankDataDtos), BankDataDto.class);
		 //应该检查银行
		 JSONObject bankReview = JSONObject.parseObject(bankDataDto.getData());
		 BankReviewDto bankReviewDto = JSON.toJavaObject(bankReview,BankReviewDto.class);
		 //银行审批结果为失败
		 if(bankDataDto.getResult().equals("false")){
			 scmFinaApplyService.processComplete(bankReviewDto.getApplyNo(),"不同意",2,0);
		 }
		 try{
			 String fileName = bankReviewDto.getApplyNo().toString()+
					 templateContract.getOriginalFilename().
							 substring(templateContract.getOriginalFilename().lastIndexOf("."));
			 //上传到minio
			 String uploadPath = CommonUtils.upload(templateContract.getInputStream(),
					 fileName,
					 "/contractTemplate",
					 CommonConstant.UPLOAD_TYPE_MINIO);
			 //临时存储
			 HttpRequest.writeToLocal(fileName,templateContract.getInputStream());
			 File file = new File(fileName);
			 //调用cfca上传合同签署
			 JSONObject contract = JSONObject.parseObject(bankDataDto.getUploadContract());
			 UploadContractVO uploadContractVO = JSON.toJavaObject(contract,UploadContractVO.class);
			 String res = CfcaOp.uploadContract(uploadContractVO, file);
			 JSONObject res_contract = JSONObject.parseObject(res);
			 Map<String,JSONObject> map = JSON.toJavaObject(res_contract, Map.class);
			 file.deleteOnExit();
			 if(map.containsKey("errorCode")){
	//				throw new JeecgBootException("上传合同签署失败");
				return Result.error(map.get("errorMessage").toString());
			 }
			 ContractVO contractVO = JSON.toJavaObject(map.get("contract"), ContractVO.class);
			 ScmFinaApply scmFinaApply = scmFinaApplyService.checkApply(bankReviewDto.getApplyNo());
			 scmFinaApply.setCfca(contractVO.getContractNo());
			 //缓存签约客户信息
			 redisUtil.set(contractVO.getContractNo(),JSON.toJSONString(uploadContractVO));
			 redisUtil.set(contractVO.getContractNo()+"_path",uploadPath);
			 scmFinaApplyService.updateById(scmFinaApply);
		 }
		 catch (Exception e){
			 return Result.error("审批失败");
		 }

		 scmFinaApplyService.executeTask("审批",bankReviewDto.getApplyNo(),1,1);
		 scmFinaApplyService.bankReview(bankReviewDto);

	 	return Result.OK("审批成功");

	 }

	 @Transactional(rollbackFor = Exception.class)
	 @ApiOperation(value = "银行接收放款接口", notes = "银行接收接口")
	 @PostMapping(value = "/bank/bankLendReceive")
	 public Result<?> bankLendReceive(@RequestParam(value = "bankDataDto") String bankDataDtos){
	 	 //转化对象
		 BankDataDto bankDataDto = JSONObject.toJavaObject(JSONObject.parseObject(bankDataDtos), BankDataDto.class);
		 JSONObject bankLending = JSONObject.parseObject(bankDataDto.getData());
		 BankLendingDto bankLendingDto = JSON.toJavaObject(bankLending,BankLendingDto.class);
		 if(bankDataDto.getResult().equals("false")){
			 scmFinaApplyService.executeTask("放款",bankLendingDto.getApplyNo(),3,1);
		 }
		 scmFinaApplyService.executeTask("放款",bankLendingDto.getApplyNo(),1,1);
		 scmFinaApplyService.lending(bankLendingDto);
	 	return Result.OK("放款成功");
	 }


	 /***/

}
